本篇是故事五的「理解」篇。
本篇要回答:同步布林介面與非同步處理語意的衝突,具體會逼系統做出哪些錯誤選擇?
Day 23 的八個狀態,對照介面上唯一的 True / False,資訊量的落差一目了然。但真正的殺傷力在於:被迫實作這個介面的人,只剩三條路可走,而三條都是錯的。
當時我以為這只是「介面設計得比較粗糙」,頂多資訊少一點。後來理解到粗糙的介面不是少給資訊,是強迫說謊——當真實狀態空間有八格、回答空間只有兩格,映射本身就是造假,差別只在往哪個方向假。
三個常見錯誤選擇,各自的謊與代價:
**選擇一:publish 成功就回 True。**把「訊息送出」冒充「遠端完成」。代價在事故日結算:呼叫端的紀錄寫滿成功,設備卻沒動——調查時所有上游證據都在說謊,Day 22 的收據效力表被整層偷換。
**選擇二:阻塞等待設備回報再回傳。**把非同步系統假裝成同步。代價是把八層旅程的總延遲搬進每一次呼叫;接著逾時、重試、重複執行、回應配對問題全部湧入這個原本「簡單」的函式——用架構換一個布林,還換不乾淨。
**選擇三:逾時就回 False。**把「期限內沒拿到成功證據」誤判成「設備明確沒有執行」。這是三者中最陰險的:呼叫端看到 False 便重送,而第一道指令可能只是慢——設備最終執行了兩次。False 與「未知」是兩種完全不同的狀態,壓縮進同一格的代價是重複執行的實體動作。
正確的狀態空間至少需要六格:
accepted 已受理,尚未執行
executing 正在執行
succeeded 已取得完成證據
failed 已取得明確失敗證據
timed_out 期限內沒有取得結果
unknown 證據不足,無法確認最終狀態
關鍵是 timed_out 與 unknown 的存在權:它們不是失敗,是誠實。系統願意說「我不知道」,呼叫端才有機會做正確的下一步——查詢狀態、冪等重送、或人工介入。
區分證據等級。已確認事實:三種選擇的機制後果由架構性質推導,皆可在任何非同步系統重現。合理推論:實務上選擇一最常見,因為它讓 demo 最順利——謊要到事故日才穿幫。
本篇結論:
非同步通訊可以知道結果,但結果必須等證據回來;Publisher 不能當場替尚未處理的遠端元件宣布成功。
下一篇(Day 25)給出可實作的替代方案:先回 Command ID,再讓執行結果循著事件回來。